package com.zzyl.nursing.service.impl;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.util.stream.Collectors;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.huaweicloud.sdk.iotda.v5.IoTDAClient;
import com.zzyl.common.constant.CacheConstants;
import com.zzyl.common.core.domain.R;

import com.zzyl.common.exception.ServiceException;
import com.zzyl.common.utils.UserThreadLocal;
import com.zzyl.framework.web.service.TokenService;
import com.zzyl.nursing.domain.*;
import com.zzyl.nursing.dto.FamilyDto;
import com.zzyl.nursing.dto.FamilyElderQueryDto;
import com.zzyl.nursing.dto.QueryDeviceDataListCountDto;
import com.zzyl.nursing.dto.UserLoginRequestDto;
import com.zzyl.nursing.mapper.*;
import com.zzyl.nursing.service.WechatService;
import com.zzyl.nursing.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import com.zzyl.nursing.service.IFamilyMemberService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

/**
 * 老人家属Service业务层处理
 *
 * @author laoYe
 * @date 2025-10-27
 */
@Service
@Slf4j
public class FamilyMemberServiceImpl extends ServiceImpl<FamilyMemberMapper, FamilyMember> implements IFamilyMemberService {
    @Autowired
    private FamilyMemberMapper familyMemberMapper;

    @Autowired
    private WechatService wechatService;

    @Autowired// 要使用若依框架
    private TokenService tokenService;
    @Autowired
    private BedMapper bedMapper;
    @Autowired
    private IoTDAClient client;

    @Autowired
    private DeviceMapper deviceMapper;
    @Autowired
    private FamilyMemberElderMapper familyMemberElderMapper;
    @Autowired
    private ElderMapper elderMapper;
    @Autowired
    private RoomMapper roomMapper;
    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;

    /**
     * 查询老人家属
     *
     * @param id 老人家属主键
     * @return 老人家属
     */
    @Override
    public FamilyMember selectFamilyMemberById(Long id) {
        return getById(id);
    }

    /**
     * 查询老人家属列表
     *
     * @param familyMember 老人家属
     * @return 老人家属
     */
    @Override
    public List<FamilyMember> selectFamilyMemberList(FamilyMember familyMember) {
        return familyMemberMapper.selectFamilyMemberList(familyMember);
    }

    /**
     * 新增老人家属
     *
     * @param familyMember 老人家属
     * @return 结果
     */
    @Override
    public int insertFamilyMember(FamilyMember familyMember) {
        return save(familyMember) ? 1 : 0;
    }

    /**
     * 修改老人家属
     *
     * @param familyMember 老人家属
     * @return 结果
     */
    @Override
    public int updateFamilyMember(FamilyMember familyMember) {
        return updateById(familyMember) ? 1 : 0;
    }

    /**
     * 批量删除老人家属
     *
     * @param ids 需要删除的老人家属主键
     * @return 结果
     */
    @Override
    public int deleteFamilyMemberByIds(Long[] ids) {
        return removeByIds(Arrays.asList(ids)) ? 1 : 0;
    }

    /**
     * 删除老人家属信息
     *
     * @param id 老人家属主键
     * @return 结果
     */
    @Override
    public int deleteFamilyMemberById(Long id) {
        return removeById(id) ? 1 : 0;
    }

    private static List<String> DEFAULT_NICKNAME_PREFIX = List.of(
            "生活更美好",
            "大桔大利",
            "日富一日",
            "好柿开花",
            "柿柿如意",
            "一椰暴富",
            "大柚所为",
            "杨梅吐气",
            "天生荔枝"
    );

    /**
     * 小程序登录
     *
     * @param dto
     * @return
     */
    @Override
    public LoginVo login(UserLoginRequestDto dto) {
        // 创建一个vo
        LoginVo vo = new LoginVo();
        //1. 获取openId
        String openId = wechatService.getOpenId(dto.getCode());
        //2. 获取用户的手机号码
        String phone = wechatService.getPhoneNumber(dto.getPhoneCode());
        //3. 通过openId查询用户信息
        FamilyMember memberInDB = lambdaQuery().eq(FamilyMember::getOpenId, openId).one();
        // 创建一个保存的实体类
        FamilyMember newFamilyMember = new FamilyMember();
        // 设置要保存的手机号码
        newFamilyMember.setPhone(phone);
        //4. 判断用户是否存在
        if (memberInDB != null) {
            vo.setNickName(memberInDB.getName());
            // 更新条件为主键id
            newFamilyMember.setId(memberInDB.getId());
            //5. 存在
            // 手机号码是否有变更，有变更则要更新
            if (!memberInDB.getPhone().equals(phone)) {
                //update 表名 set 字段名 = 值 where id = ?, 明确更新的字段
                updateById(newFamilyMember);
            }
        } else {
            //6. 不存在,新增
            newFamilyMember.setOpenId(openId);
            // 昵称
            // 随机组装昵称，词组+手机号后四位
            String nickName = generateNickname(phone);
            newFamilyMember.setName(nickName);
            save(newFamilyMember);
            vo.setNickName(nickName);
        }
        //7. 把用户id与nickname封装到token返回
        Map<String, Object> claims = new HashMap<String, Object>();
        claims.put("userId", newFamilyMember.getId());
        claims.put("nickName", vo.getNickName());
        String token = tokenService.createToken(claims);
        vo.setToken(token);
        return vo;
    }

     /**
     * 按天统计查询指标数据
     */
    @Override
    public List<QueryDeviceDataListCountVo> queryDeviceDataListByDay(QueryDeviceDataListCountDto queryDeviceDataListCountDto) {
        // 转换开始时间
        LocalDateTime startTime = Instant.ofEpochMilli(queryDeviceDataListCountDto.getStartTime())
                .atZone(ZoneId.systemDefault())
                .toLocalDateTime();
        // 转换结束时间
        LocalDateTime endTime = Instant.ofEpochMilli(queryDeviceDataListCountDto.getEndTime())
                .atZone(ZoneId.systemDefault())
                .toLocalDateTime();
        // 调用mapper查询具体数据
        List<QueryDeviceDataListCountVo> queryDeviceDataListCountVo = deviceMapper.selectDeviceDataListByDay(queryDeviceDataListCountDto.getIotId(), queryDeviceDataListCountDto.getFunctionId(), startTime, endTime);
        return queryDeviceDataListCountVo;
    }

    /**
     * 按周统计查询指标数据
     *
     */
    @Override
    public List<QueryDeviceDataListCountVo> queryDeviceDataListByWeek(QueryDeviceDataListCountDto queryDeviceDataListCountDto) {
        // 转换开始时间
        LocalDateTime startTime = Instant.ofEpochMilli(queryDeviceDataListCountDto.getStartTime())
                .atZone(ZoneId.systemDefault())
                .toLocalDateTime();
        // 转换结束时间
        LocalDateTime endTime = Instant.ofEpochMilli(queryDeviceDataListCountDto.getEndTime())
                .atZone(ZoneId.systemDefault())
                .toLocalDateTime();
        // 调用mapper查询具体数据
        List<QueryDeviceDataListCountVo> queryDeviceDataListCountVo = deviceMapper
                .selectDeviceDataListByWeek(queryDeviceDataListCountDto.getIotId()
                        , queryDeviceDataListCountDto.getFunctionId(),
                        startTime, endTime);
        return queryDeviceDataListCountVo;
    }




    /**
     * 生成随机昵称
     *
     * @param phone
     * @return
     */
    private String generateNickname(String phone) {
        Random r = new Random();
        int prefixIndex = r.nextInt(DEFAULT_NICKNAME_PREFIX.size());
        String prefix = DEFAULT_NICKNAME_PREFIX.get(prefixIndex);
        // 手机号后四位
        String suffix = phone.substring(phone.length() - 4);
        return prefix + suffix;
    }

    /**
     * 新增老人家属
     *
     * @param
     */


    @Override
    public void add(FamilyDto familyDto) {
        // 1. 校验必填字段
        if (familyDto == null || StringUtils.isEmpty(familyDto.getIdCard()) ||
                StringUtils.isEmpty(familyDto.getName())) {
            throw new RuntimeException("姓名和身份证号不能为空");
        }

        // 2. 查询老人是否存在且状态为“入住中”
        Elder elder = elderMapper.selectOne(new LambdaQueryWrapper<Elder>()
                .eq(Elder::getIdCardNo, familyDto.getIdCard())
                .eq(Elder::getName, familyDto.getName())
                .eq(Elder::getStatus, 4)); // 状态为“入住中”

        if (elder == null) {
            throw new RuntimeException("未找到该老人，请确认姓名和身份证号是否正确");
        }

        // 3. 获取当前登录家属 ID
        Long familyMemberId = UserThreadLocal.getUserId();
        if (familyMemberId == null) {
            throw new RuntimeException("当前用户未登录");
        }

        // 4. 构建关联对象
        FamilyMemberElder familyMemberElder = new FamilyMemberElder();
        familyMemberElder.setElderId(elder.getId());
        familyMemberElder.setFamilyMemberId(familyMemberId);
        familyMemberElder.setRemark(familyDto.getRemark());

        // 5. 插入数据库
        // 5. 插入数据库
        familyMemberElderMapper.insert(familyMemberElder);

    }

    /**
     * 查询当前用户家人列表
     *
     * @return
     */

    @Override
    public List<FamilyMemberVo> listByFamilyMemberId() {
        //先获取当前用户ID
        Long familyMemberId = UserThreadLocal.getUserId();
        if (familyMemberId == null) {
            throw new RuntimeException("当前用户未登录");
        }
        //查询家属与老人的关系
        List<FamilyMemberElder> relations = familyMemberElderMapper.selectList(
                new LambdaQueryWrapper<FamilyMemberElder>()
                        .eq(FamilyMemberElder::getFamilyMemberId, familyMemberId)
        );
        List<FamilyMemberVo> collect = relations.stream().map(r -> {
            FamilyMemberVo vo = new FamilyMemberVo();
            vo.setId(r.getId());
            vo.setFamilyMemberId(r.getFamilyMemberId());
            vo.setElderId(r.getElderId());

            //获取老人名字
            Elder elder = elderMapper.selectById(r.getElderId());
            vo.setElderName(elder.getName());
            return vo;
        }).collect(Collectors.toList());
        return collect;
    }

    /**
     * 分页查询当前登录的家属的老人
     *
     * @return
     */
    @Override
    public List<FamilyElderDetailVo> pageQuery(FamilyElderQueryDto dto) {
        //先获取当前用户ID
        Long familyMemberId = UserThreadLocal.getUserId();
        if (familyMemberId == null) {
            throw new RuntimeException("当前用户未登录");
        }
        LambdaQueryWrapper<FamilyMemberElder> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(FamilyMemberElder::getFamilyMemberId, familyMemberId);


        Page<FamilyMemberElder> page = new Page<>(dto.getPageNum(), dto.getPageSize());
        Page<FamilyMemberElder> pageResult = familyMemberElderMapper.selectPage(page, queryWrapper);

        //转为vo列表
        List<FamilyElderDetailVo> voList = pageResult.getRecords().stream().map(r -> {
            FamilyElderDetailVo vo = new FamilyElderDetailVo();
            vo.setMid(r.getId());
            vo.setElderId(r.getFamilyMemberId());
            vo.setElderId(r.getElderId());
            vo.setMremark(r.getRemark());
            // 查询老人详情
            Elder elder = elderMapper.selectById(r.getElderId());
            if (elder != null) {
                vo.setName(elder.getName());
                vo.setImage(elder.getImage());
                vo.setBedNumber(elder.getBedNumber());

                // 获取床位信息（关联 Bed 表）
                if (elder.getBedId() != null) {
                    Bed bed = bedMapper.selectById(elder.getBedId());
                    if (bed != null) {
                        // 通过 roomId 关联 Room 表获取 roomTypeName
                        Room room = roomMapper.selectById(bed.getRoomId());
                        if (room != null) {
                            vo.setTypeName(room.getTypeName()); // 使用 roomName 作为 typeName
                        }
                    }
                }
                // 获取IoT设备信息（关联 IotDevice 表）
                Device device = elderMapper.selectDeviceByElderId(elder.getId());
                if (ObjectUtils.isEmpty( device)) {
                    throw new RuntimeException("未找到IoT设备信息");

                }
                vo.setIotId(device.getIotId());
                vo.setDeviceName(device.getDeviceName());
                vo.setProductKey(device.getProductKey());


            }
            return vo;

        }).collect(Collectors.toList());

    return voList;
    }



    /**
     * 查询健康数据
     * @param iotId
     * @return
     */
    @Override
    public List<DeviceShadowDataVo> queryServiceProperties(String iotId) {
        log.info("查询设备数据");
        //获取redis中这个设备最新的数据
        String jsonStr = (String) redisTemplate.opsForHash().get(
                CacheConstants.IOT_DEVICE_LAST_DATA,
                iotId
        );
        if (StrUtil.isEmpty(jsonStr)){
            return null;
        }
        // 反序列化为 Java 对象
        List<DeviceData> deviceDataList = JSONUtil.toList(jsonStr, DeviceData.class);
        if (CollUtil.isEmpty(deviceDataList)){
            return new ArrayList<>();
        }
        return deviceDataList.stream()
                .map(deviceData -> {
                    DeviceShadowDataVo vo = new DeviceShadowDataVo();
                    vo.setFunctionId(deviceData.getFunctionId());
                    vo.setEventTime(deviceData.getAlarmTime());
                    vo.setValue(deviceData.getDataValue());
                    return vo;
                })
                .collect(Collectors.toList());

    }


}
